Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Host function generic_hash() with blake2b/blake3 support. #4411

Closed

Conversation

koxu1996
Copy link

@koxu1996 koxu1996 commented Nov 13, 2023

In order to support Zero Knowledge software, cryptography related utils should be implemented as a host functions, otherwise execution cost would be too unacceptable. For example running Risc0 VM proof verification for simple sum of squares takes more than 6000 CSPR. The underlying hash used: sha256.

This PR adds host function called generic_hash(input, type) with support for the following types:

  • HashAlgoType::Blake2b - used existing blake2b implementation,
  • HashAlgoType::Blake3b - blake3 library was introduced.

We expect to add more algorithms, i.e. sha256, keccak, poseidon.

Example usage

Smart contract:

#![no_std]
#![no_main]

extern crate alloc;

use alloc::format;
use casper_contract::contract_api::{crypto, runtime};
use casper_types::HashAlgoType;

#[no_mangle]
pub extern "C" fn call() {
    let input = "casper".as_bytes();
    runtime::print(&format!("Input: {:?}", input));

    let blake2b = crypto::generic_hash(input, HashAlgoType::Blake2b);
    runtime::print(&format!("Blake2b hash: {:?}", blake2b));

    let blake3 = crypto::generic_hash(input, HashAlgoType::Blake3);
    runtime::print(&format!("Blake3 hash: {:?}", blake3));
}

Node output:

Input: [99, 97, 115, 112, 101, 114]
Blake2b hash: [163, 40, 63, 203, 149, 170, 125, 252, 231, 127, 90, 198, 44, 250, 234, 42, 1, 199, 20, 158, 150, 188, 25, 205, 21, 106, 255, 40, 204, 65, 45, 196]
Blake3 hash: [122, 158, 116, 51, 175, 213, 20, 50, 237, 63, 251, 230, 53, 2, 233, 86, 36, 159, 195, 109, 254, 108, 189, 210, 233, 1, 93, 219, 226, 1, 50, 217]

Considerations

1. AssemblyScript support

Is AssemblyScript binding required? I am pretty sure no one uses it.

2. Gas cost

For now, I used the same cost for generic_hash() as defined for blake2() - default fixed value 200. I can do benchmarks for WASM bytecode execution, but is there any conversion ratio between CPU time and execution cost?

3. Place for core hashes implementation

Blake2b is implemented in types package, which does not seem to be reasonable. I added blake3 to new module crypto in execution engine, but I am not fully sure if this is the correct place.

4. Single vs multiple host function

Do we want to introduce separate host functions for each hash algorithm?

5. Place for generic_hash() in contract API

I was thinking of using runtime, but finally decided to create new crypto module.

Will be used to introduce hashing method for runtime.
Placed in new `crypto` module under `runtime`.
Will be used to switch between different hashing algorithms.
Note: no gas charging was introduced yet.
Inspired by `FunctionIndex::Blake2b`, which is also not researched
in terms of execution cost.
Note: new module `crypto` was introduced.
@koxu1996 koxu1996 marked this pull request as ready for review November 13, 2023 16:29
@koxu1996
Copy link
Author

Closed in favor of #4412, that targets feat-1.6 branch.

@koxu1996 koxu1996 closed this Nov 13, 2023
@koxu1996 koxu1996 deleted the feature/generic-hash-ffi branch November 20, 2023 12:42
@devendran-m
Copy link
Contributor

Related Issue (created to take the work forward) #4892

casperlabs-bors-ng bot added a commit that referenced this pull request Oct 15, 2024
4903: Implement generic_hash() host function to support hashing algorithms r=igor-casper a=igor-casper

This PR directly addresses #4892, referencing #4411 as prior work.

Adds host function called generic_hash(input, type) with support for the following types:
- HashAlgorithm::Blake2b - using the existing blake2b implementation,
- HashAlgorithm::Blake3 - introducing the blake3 library,
- HashAlgorithm::Sha256 - introducing the sha2 library,

**Example usage**
```rs
#![no_std]
#![no_main]

extern crate alloc;
use alloc::string::String;

use casper_contract::contract_api::cryptography;
use casper_types::crypto::HashAlgorithm;

#[no_mangle]
pub extern "C" fn call() {
    let data = "sha256 hash test";
    let expected = [0x29, 0xD2, 0xC7, 0x7B, 0x39, 0x7F, 0xF6, 0x9E, 0x25, 0x0D, 0x81, 0xA3, 0xBA, 0xBB, 0x32, 0xDE, 0xFF, 0x3C, 0x2D, 0x06, 0xC9, 0x8E, 0x5E, 0x73, 0x60, 0x54, 0x3C, 0xE4, 0x91, 0xAC, 0x81, 0xCA];

    let hash = cryptography::generic_hash(data, HashAlgorithm::Sha256);
    
    assert_eq!(
        hash, expected,
        "Hash mismatch"
    );
}
```

**Notes**
- Blake2 is implemented in the types crate and it's been that way for some time, ideally it would be moved into the cryptography module where blake3 and sha256 reside
- The costs were referenced from #4411

Co-authored-by: igor-casper <[email protected]>
Co-authored-by: igor-casper <[email protected]>
casperlabs-bors-ng bot added a commit that referenced this pull request Oct 15, 2024
4903: Implement generic_hash() host function to support hashing algorithms r=igor-casper a=igor-casper

This PR directly addresses #4892, referencing #4411 as prior work.

Adds host function called generic_hash(input, type) with support for the following types:
- HashAlgorithm::Blake2b - using the existing blake2b implementation,
- HashAlgorithm::Blake3 - introducing the blake3 library,
- HashAlgorithm::Sha256 - introducing the sha2 library,

**Example usage**
```rs
#![no_std]
#![no_main]

extern crate alloc;
use alloc::string::String;

use casper_contract::contract_api::cryptography;
use casper_types::crypto::HashAlgorithm;

#[no_mangle]
pub extern "C" fn call() {
    let data = "sha256 hash test";
    let expected = [0x29, 0xD2, 0xC7, 0x7B, 0x39, 0x7F, 0xF6, 0x9E, 0x25, 0x0D, 0x81, 0xA3, 0xBA, 0xBB, 0x32, 0xDE, 0xFF, 0x3C, 0x2D, 0x06, 0xC9, 0x8E, 0x5E, 0x73, 0x60, 0x54, 0x3C, 0xE4, 0x91, 0xAC, 0x81, 0xCA];

    let hash = cryptography::generic_hash(data, HashAlgorithm::Sha256);
    
    assert_eq!(
        hash, expected,
        "Hash mismatch"
    );
}
```

**Notes**
- Blake2 is implemented in the types crate and it's been that way for some time, ideally it would be moved into the cryptography module where blake3 and sha256 reside
- The costs were referenced from #4411

Co-authored-by: igor-casper <[email protected]>
Co-authored-by: igor-casper <[email protected]>
casperlabs-bors-ng bot added a commit that referenced this pull request Oct 18, 2024
4903: Implement generic_hash() host function to support hashing algorithms r=EdHastingsCasperAssociation a=igor-casper

This PR directly addresses #4892, referencing #4411 as prior work.

Adds host function called generic_hash(input, type) with support for the following types:
- HashAlgorithm::Blake2b - using the existing blake2b implementation,
- HashAlgorithm::Blake3 - introducing the blake3 library,
- HashAlgorithm::Sha256 - introducing the sha2 library,

**Example usage**
```rs
#![no_std]
#![no_main]

extern crate alloc;
use alloc::string::String;

use casper_contract::contract_api::cryptography;
use casper_types::crypto::HashAlgorithm;

#[no_mangle]
pub extern "C" fn call() {
    let data = "sha256 hash test";
    let expected = [0x29, 0xD2, 0xC7, 0x7B, 0x39, 0x7F, 0xF6, 0x9E, 0x25, 0x0D, 0x81, 0xA3, 0xBA, 0xBB, 0x32, 0xDE, 0xFF, 0x3C, 0x2D, 0x06, 0xC9, 0x8E, 0x5E, 0x73, 0x60, 0x54, 0x3C, 0xE4, 0x91, 0xAC, 0x81, 0xCA];

    let hash = cryptography::generic_hash(data, HashAlgorithm::Sha256);
    
    assert_eq!(
        hash, expected,
        "Hash mismatch"
    );
}
```

**Notes**
- Blake2 is implemented in the types crate and it's been that way for some time, ideally it would be moved into the cryptography module where blake3 and sha256 reside
- The costs were referenced from #4411

Co-authored-by: igor-casper <[email protected]>
Co-authored-by: igor-casper <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants